using System;
using System.Collections;
using Microsoft.VisualStudio.TestTools.Common;
using Microsoft.VisualStudio.TestTools.Vsip;
using Microsoft.VisualStudio.TestTools.Exceptions;
using System.Globalization;
using NUnitForVSTS.NUnitTest.Properties;
using System.Diagnostics;

namespace NUnitForVSTS.NUnitTest
{
    /// <summary>
    /// NNunit Test Interface Provider components
    /// http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.common.tip.aspx
    /// Provides extentions to the test interface
    /// </summary>

	public class NUnitTestTip : Tip
	{
        private ITmi _tmi;

        /// <summary>
        /// Initializes a new instance of the <see cref="NUnitTestTip"/> class.
        /// </summary>
        /// <param name="tmi">The tmi.</param>
		public NUnitTestTip(ITmi tmi) : base()
        {
            _tmi = tmi;
        }

        #region ITip Implementation 

		/// <summary>
		/// Returns TestType object for given TIP. There is 1:1 between TIPs and TestTypes
		/// </summary>
		/// <value>The Test Type that this TIP is for. This value is never null</value>
        public override TestType TestType
        {
            get { return UnitTest.NUnitTestType; }
        }

		/// <summary>
		/// Loads elements from specified location into memory
		/// 
		/// This method uses exceptions for error conditions -- Not return values.
		/// </summary>
		/// <param name="location">Location to load tests from.</param>
		/// <param name="projectData">Project information object.</param>
		/// <param name="warningHandler">Warning handler that processes warnings.</param>
		/// <returns>The data that has been loaded</returns>
		public override ICollection Load(string location, ProjectData projectData, IWarningHandler warningHandler)
		{
			SourceFileExplorer explorer = new SourceFileExplorer();
			ICollection tests = explorer.Read(location, projectData, warningHandler);
            Trace.WriteLine(string.Format(CultureInfo.CurrentUICulture, VSPackage.NUnitTestTip_AmountTestsLoaded, tests.Count));

            return tests; 
		}

		/// <summary>
		/// Saves specified set of tests in a specified location.
		/// Tests are to be written to the location in the order in which they appear in the array.
		/// </summary>
		/// <param name="tests">Tests to save. Storage parameter on tests must be ignored.</param>
		/// <param name="location">Location where tests are to be saved.</param>
		/// <param name="projectData">Project information object.</param>
		public override void Save(ITestElement[] tests, string location, ProjectData projectData)
		{
			/*MyTestAssertHelper.ArrayNotNullOrEmpty(tests, "tests");
			MyTestAssertHelper.StringNotNullOrEmpty(location, "location");

			// Open the test file on disk
			FileStream fs = new FileStream(location, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
			
			using (StreamWriter sw = new StreamWriter(fs))
			{
				// Go Through all the tests and save them into the previously opened file
				foreach (ITestElement testelem in tests)
				{
					MyTest test = testelem as MyTest;
					sw.WriteLine("{0},{1},{2}", test.Name, test.Description, test.CommandLine);
				}
			}*/
		}

		/// <summary>
		/// Merges results arrived from the wire (never null) with results in memory (may be null)
		/// </summary>
		/// <param name="inMemory"></param>
		/// <param name="fromTheWire"></param>
		/// <returns>result to be put in memory, never null</returns>
		public override TestResult MergeResults(TestResult inMemory, TestResultMessage fromTheWire)
		{
            TestResult resultFromWire = fromTheWire as TestResult;
            if (fromTheWire == null || resultFromWire == null)
            {
                throw new EqtDataException("MergeResults");
            }
            if (!(resultFromWire is UnitTestResult))
            {
                resultFromWire = new UnitTestResult(resultFromWire);
            }	

			// If the in memory result is not there yet, we need to
			// create one for test framework to work with
			if (inMemory == null)
			{
                TestResult mem = new UnitTestResult(fromTheWire.ComputerName, fromTheWire.Id.RunId, resultFromWire.Test);
				mem.Outcome =resultFromWire.Outcome;
                
				return mem; // Send it back for use by test framework
			}

            if (fromTheWire != null)
            {
                if (inMemory != null)
                {
                    resultFromWire.Outcome = TestOutcomeHelper.GetAggregationOutcome(new TestResult[] { inMemory, resultFromWire });
                }
                return resultFromWire;
            }
            else
            {
                return inMemory;
            }
		}

		#endregion


    }
}